import json
import re
import logging
from datetime import datetime

from django.shortcuts import render, redirect, HttpResponse
from django.http import Http404, FileResponse

from mac import models
from mac.forms import notice_forms
from mac.utils import page

logger = logging.getLogger(__name__)


def create_delivery_order(request):
    '''
    创建出货通知单
    :param request:
    :return:
    '''
    if request.method == 'GET':
        notice_form = notice_forms.NoticeAddForm()
        return render(request, 'create_delivery_order.html', {'notice_form': notice_form})
    notice_form = notice_forms.NoticeAddForm(request.POST)
    if notice_form.is_valid():
        notice_obj = notice_form.save(commit=False)
        notice_obj.user = request.mac.user
        notice_obj.save()
        return redirect('query_delivery_order')
    return render(request, 'create_delivery_order.html', {'notice_form': notice_form})


def edit_delivery_order(request, oid):
    '''
    修改出货通知单
    :param request:
    :return:
    '''
    order_obj = models.Notice.objects.filter(id=oid).first()
    if request.method == 'GET':
        notice_form = notice_forms.NoticeEditForm(instance=order_obj)
        return render(request, 'create_delivery_order.html', {'notice_form': notice_form, "oid": oid})
    notice_form = notice_forms.NoticeEditForm(data=request.POST, instance=order_obj)
    if notice_form.is_valid():
        try:
            notice_form.save()
        except UnicodeError as e:
            logger.error(e)
            return render(request, '500.html')
        models.Notice.objects.filter(id=oid).update(examine=0, status=0)
        return redirect('query_delivery_order')
    return render(request, 'create_delivery_order.html', {'notice_form': notice_form, "oid": oid})


def query_delivery_order(request):
    '''
    查询出货通知单
    :param request:
    :return:
    '''
    if request.method == 'POST':
        mac_address = request.POST.get('mac_address')
        date_rang = request.POST.get('date_rang')
        Audit_status = request.POST.get('Audit_status')
        model = request.POST.get('model')
        if request.mac.user.depart_id.all()[0].department_name == '系统管理部门':
            notice_query = models.Notice.objects.all().order_by('-delivery_date')
        else:
            notice_query = models.Notice.objects.filter(user=request.mac.user).order_by('-delivery_date')
        set_list = []
        mac_set = set()
        if mac_address:
            for i in notice_query:
                if mac_address in i.mac_address.split('\r\n'):
                    mac_set.add(i)
                    break
            set_list.append(mac_set)
        date_set = set()
        if date_rang:
            date_start = date_rang.split(' - ')[0]
            date_end = date_rang.split(' - ')[1]
            date_start = datetime.strptime(date_start, '%Y-%m-%d')
            date_end = datetime.strptime(date_end, '%Y-%m-%d')
            for i in notice_query:
                if i.delivery_date.replace(tzinfo=None) >= date_start and i.delivery_date.replace(tzinfo=None) <= date_end:
                    date_set.add(i)
            set_list.append(date_set)
        status_set = set()
        if Audit_status and Audit_status == '待处理' or Audit_status == '备货中':
            if Audit_status == '待处理':
                Audit_status = 0
            else:
                Audit_status = 1
            for i in notice_query:
                if Audit_status == i.status:
                    status_set.add(i)
            set_list.append(status_set)
        model_set = set()
        if model:
            mac_query = models.Macs.objects.filter(model=model).values_list('mac')
            mac_lst = []
            for i in mac_query:
                mac_lst.append(i[0])
            for i in notice_query:
                for y in i.mac_address.split('\r\n'):
                    if y in mac_lst:
                        model_set.add(i)
            set_list.append(model_set)
        res = None
        a = 0
        for i in set_list:
            if a == 0:
                res = i
            else:
                res = res & i
            a += 1
        notice_query = res
    else:
        if request.mac.user.depart_id.all()[0].department_name == '系统管理部门':
            notice_query = models.Notice.objects.all().order_by('-delivery_date')
        else:
            notice_query = models.Notice.objects.filter(user=request.mac.user).order_by('-delivery_date')
    if isinstance(notice_query, set):
        notice_query = list(reversed(list(notice_query)))
        notice_count = len(notice_query)
    else:
        notice_count = notice_query.count()
    pages = request.GET.get('page')
    notice_page_size = request.GET.get('notice_page_size')
    if not notice_page_size:
        notice_page_size = request.session.get('notice_page_size', 20)
    else:
        request.session['notice_page_size'] = request.GET.get('notice_page_size')

    notice_obj = page.PageInfo(current_page=pages,
                              all_count=notice_count,
                              url='/query_delivery_order/',
                              per_page=notice_page_size)
    notice_query = notice_query[notice_obj.start():notice_obj.end()]
    return render(request, 'query_delivery_order.html', {"notice_query": notice_query,
                                                          'pages': notice_obj.pager(),
                                                          'notice_page_size': notice_page_size,
                                                          'notice_count': notice_count
                                                          })


def details_delivery_order(request, oid):
    '''
    出货单mac详情
    :param request:
    :param oid:
    :return:
    '''
    order_query = models.Notice.objects.filter(id=oid).first()
    mac_address = order_query.mac_address
    mac_address = mac_address.replace('\r', '')
    mac_list = mac_address.split('\n')
    mac_query = models.Macs.objects.filter(mac__in=mac_list)
    mac_count = mac_query.count()
    pages = request.GET.get('page')
    page_size = request.GET.get('page_size')
    if not page_size:
        page_size = request.session.get('page_size', 20)
    else:
        request.session['page_size'] = request.GET.get('page_size')
    mac_order_obj = page.PageInfo(current_page=pages,
                                   all_count=mac_count,
                                   url='/details_delivery_order/' + oid,
                                   per_page=page_size)
    mac_order_page_obj = mac_query[mac_order_obj.start():mac_order_obj.end()]
    return render(request, 'delivery_mac_details.html', {'mac_query': mac_order_page_obj,
                                                         'pages': mac_order_obj.pager(),
                                                         'page_size': page_size,
                                                         'mac_count': mac_count,
                                                         'oid': oid
                                                         })


def check_mac(request):
    '''
    验证mac是否在数据库中存在
    :param request:
    :return:
    '''
    res = {}
    mac_values = request.POST.get('mac_values')
    if not mac_values or not mac_values.strip('\n'):
        res['empty'] = True
        return HttpResponse(json.dumps(res))
    mac_values = mac_values.replace('\r', '')
    mac_list = mac_values.split('\n')
    strip_mac_list = []
    for i in mac_list:
        if i:
            strip_mac_list.append(i)
    mac_lst_tuple = models.Macs.objects.all().values_list('mac')
    mac_list_all = []
    mac_list_error = []
    mac_format_error = []
    for i in mac_lst_tuple:
        mac_list_all.append(i[0])
    for i in strip_mac_list:
        re_mac = re.match(r'^[0-9a-fA-F]{12}$', i)
        if not re_mac:
            mac_format_error.append(i)
        if i not in mac_list_all:
            mac_list_error.append(i)
    if mac_format_error:
        res['format_error'] = mac_format_error
        return HttpResponse(json.dumps(res))
    res['no_exist'] = mac_list_error
    return HttpResponse(json.dumps(res))


def order_examine(request):
    '''
    出货单审核
    :param request:
    :return:
    '''
    res = {'status': True}
    if request.method == 'GET':
        order_id = request.GET.get('order_id')
        return render(request, "delivery_examine.html", {'order_id': order_id})
    examine_result = request.POST.get('examine_result')
    order_id = int(request.POST.get('order_id'))
    failed_desc = request.POST.get('failed_desc', None)
    print(failed_desc)
    if examine_result == '通过':
        models.Notice.objects.filter(id=order_id).update(examine=2, status=1)
        if models.ExamineDesc.objects.filter(delivery_order_id=order_id):
            models.ExamineDesc.objects.filter(delivery_order_id=order_id).delete()
    else:
        if not failed_desc or len(failed_desc.strip(' ')) < 10:
            res['status'] = False
            res['failed_desc'] = '未通过原因描述至少10个字符！！'
            return HttpResponse(json.dumps(res))
        models.Notice.objects.filter(id=order_id).update(examine=1)
        a, b = models.ExamineDesc.objects.update_or_create(delivery_order_id=order_id,
                                                            defaults={'examine_desc': failed_desc})
        print(a, b)
    return HttpResponse(json.dumps(res))


def show_examine(request):
    '''
    查看审核未通过的原因
    :param request:
    :return:
    '''
    order_id = request.GET.get('order_id', None)
    try:
        examine_desc = models.ExamineDesc.objects.filter(delivery_order_id=order_id).first().examine_desc
    except AttributeError as e:
        logger.error(e)
        return render(request, '500.html')
    return render(request, 'show_examine.html', {'examine_desc': examine_desc})


def download_delivery_mac(request, oid):
    '''
    下载出货mac详情
    :param request:
    :param oid:
    :return:
    '''
    order_query = models.Notice.objects.filter(id=oid).first()
    mac_address = order_query.mac_address
    mac_address = mac_address.replace('\r', '')
    mac_list = mac_address.split('\n')
    mac_query = models.Macs.objects.filter(mac__in=mac_list)
    dict_mac = mac_query.values('mac', 'uuid', 'model', 'board', 'country', 'deviceid',
                               'secret', 'mqtt', 'private_key', 'public_key', 'address',
                               'endpoint_host', 'endpoint_port', 'future'
                               )
    macs_str = ''
    item = list(dict_mac)[0]
    for key in item.keys():
        macs_str = macs_str + key + ','
    macs_str = macs_str + '\r\n'
    for item in list(dict_mac):
        for value in item.values():
            macs_str = macs_str + value + ','
        macs_str = macs_str[:-1] + '\r\n'
    # file_name = date + '-' + dict_mac[0]['model'] + '-' + dict_mac[0]['mac'] + '-' + str(list_mac.count()) + '.csv'
    file_name = order_query.notice_number + '.csv'
    try:
        response = FileResponse(macs_str)
        response['content_type'] = "application/octet-stream"
        response['Content-Disposition'] = 'attachment; filename=' + file_name
        return response
    except Exception as e:
        logger.error(e)
        raise Http404
